#pragma once

struct bignum_st;

namespace auth
{

    class BigNumber
    {
    public:
        BigNumber();
        BigNumber(const BigNumber& bn);
        BigNumber(unsigned int);
        ~BigNumber();
        void SetDword(unsigned int);
        void SetQword(unsigned long long);
        void SetBinary(const unsigned char* bytes, int len);
        void SetHexStr(const char* str);

        void SetRand(int numbits);

        BigNumber operator=(const BigNumber& bn);
        BigNumber operator+=(const BigNumber& bn);
        BigNumber operator+(const BigNumber& bn)
        {
            BigNumber t(*this);
            return t += bn;
        }
        BigNumber operator-=(const BigNumber& bn);
        BigNumber operator-(const BigNumber& bn)
        {
            BigNumber t(*this);
            return t -= bn;
        }
        BigNumber operator*=(const BigNumber& bn);
        BigNumber operator*(const BigNumber& bn)
        {
            BigNumber t(*this);
            return t *= bn;
        }
        BigNumber operator/=(const BigNumber& bn);
        BigNumber operator/(const BigNumber& bn)
        {
            BigNumber t(*this);
            return t /= bn;
        }
        BigNumber operator%=(const BigNumber& bn);
        BigNumber operator%(const BigNumber& bn)
        {
            BigNumber t(*this);
            return t %= bn;
        }
        bool isZero() const;
        BigNumber ModExp(const BigNumber& bn1, const BigNumber& bn2);
        BigNumber Exp(const BigNumber&);
        int GetNumBytes(void);
        struct ::bignum_st* BN() { return _bn; }
        unsigned int AsDword();
        unsigned char* AsByteArray(int minSize = 0);
        unsigned char* AsByteArray(int minSize, bool reverse);
        const char* AsHexStr();
        const char* AsDecStr();

    private:
        struct ::bignum_st* _bn;
        unsigned char* _array;
    };

}